"""
代码尝试专用脚本
- 用于调试、测试新功能或片段
"""

import time
from tqdm import tqdm
import pandas as pd
import logging
from netcore import (
    stability_analysis,
    bootstrap_centrality,
    centrality_anova_by_year,
    compare_jaccard,
    compare_centrality_ks,
    calc_residuals,
    build_network,
    print_node_metrics,
    get_network_overall_metrics,
    print_network_overall_metrics,
    fill_mode,
    preprocess_city_df,
    residual_network_by_year
)
import os
from plot import draw_network
import yaml
from matplotlib.font_manager import FontProperties
from tabulate import tabulate
import matplotlib.pyplot as plt

# 读取 config.yaml
with open('config.yaml', 'r', encoding='utf-8') as f:
    config = yaml.safe_load(f)

CSV_PATH = config.get('csv_path')
FIELDS_CORE = list(config.get('core_name_map', {}).keys())
CORE_NAME_MAP = config.get('core_name_map', {})
CONTROL_VARS = config.get('control_vars')
FIGURES_DIR = config.get('figures_dir', 'figures')
THRESHOLD = config.get('threshold', 0.1)
CH_FONT_NAME = config.get('ch_font', 'Heiti TC')
ch_font = FontProperties(fname=None, family=CH_FONT_NAME)

try:
    df = pd.read_csv(CSV_PATH, low_memory=False)
    logging.info(f"CSV文件 {CSV_PATH} 读取成功，数据量：{df.shape[0]} 行，{df.shape[1]} 列。")
except Exception as e:
    logging.error(f"CSV文件读取失败：{e}")
    raise

if "城乡" not in df.columns:
    logging.error("未找到城乡字段，无法筛选城市样本。")
    raise ValueError("未找到城乡字段")

city_df = preprocess_city_df(df)
logging.info(f"城市样本筛选后行数: {len(city_df)}")

# 检查核心变量字段是否全部存在（在城市样本筛选和主观得分生成后）
missing_fields = [field for field in FIELDS_CORE if field not in city_df.columns]
if missing_fields:
    logging.warning(f"数据表缺少以下核心变量字段，无法分析：{missing_fields}")
    print(f"⚠️ 数据表缺少以下核心变量字段，无法分析：{missing_fields}")
    raise ValueError(f"缺少字段: {missing_fields}")

# 独热编码区县
if "区县" in city_df.columns:
    district_dummies = pd.get_dummies(city_df["区县"], prefix="区县")
    city_df = pd.concat([city_df, district_dummies], axis=1)
    control_vars = [v for v in CONTROL_VARS if v != "区县"] + list(district_dummies.columns)
else:
    control_vars = CONTROL_VARS.copy()

all_vars = list(set(FIELDS_CORE + control_vars))
df_net = city_df[FIELDS_CORE + control_vars].copy()
df_net = df_net.dropna(subset=FIELDS_CORE)
df_net = fill_mode(df_net, control_vars)

# 只绘制五个核心变量显著且相关系数绝对值大于阈值的网络图
data = df_net[FIELDS_CORE].dropna()
G = build_network(data, FIELDS_CORE, CORE_NAME_MAP, threshold=THRESHOLD)
draw_network(G, title="核心变量网络图", save_path=f"{FIGURES_DIR}/核心变量网络图.png", ch_font=ch_font, edge_threshold=THRESHOLD)

# 1. 计算每个核心变量的残差（控制所有控制变量）
residuals = calc_residuals(df_net, FIELDS_CORE, control_vars)

# 2. 用残差做网络分析
# 控制变量后核心变量显著相关网络（红色节点）
G2 = build_network(residuals, FIELDS_CORE, CORE_NAME_MAP, threshold=0.1, pval_cut=0.05)
net_img_path3 = os.path.join(FIGURES_DIR, "控制变量后核心变量显著相关网络图.png")
draw_network(G2, "控制变量后核心变量显著相关网络", net_img_path3, ch_font, node_color='red')

# 打印节点指标
print_node_metrics(G, "核心变量显著相关网络")
print_node_metrics(G2, "控制变量后核心变量显著相关网络")
print_network_overall_metrics(G, "核心变量显著相关网络")
print_network_overall_metrics(G2, "控制变量后核心变量显著相关网络")

# 按年份绘制残差网络图
fig_path = residual_network_by_year(df_net, FIELDS_CORE, control_vars, CORE_NAME_MAP, ch_font, FIGURES_DIR, threshold=0.1, pval_cut=0.05)

# 在网络分析部分添加统计检验
print("\n" + "="*30 + " 中心性指标统计检验 " + "="*30)
# Bootstrap分析
print("\n【Bootstrap中心性指标置信区间(95%)】")
ci_results = bootstrap_centrality(G2)  # 对控制变量后的网络进行分析
print(tabulate(ci_results, headers='keys', tablefmt='grid'))

# 年份间方差分析
centrality_anova_by_year(df_net, FIELDS_CORE, control_vars, CORE_NAME_MAP)

# 在绘制残差网络图之前添加网络稳定性分析
print("\n" + "="*30 + " 网络稳定性分析 " + "="*30)
# 对原始数据进行稳定性分析
stability_results = stability_analysis(data, FIELDS_CORE, CORE_NAME_MAP)
print("\n【原始数据不同阈值下的网络特征】")
print(tabulate(stability_results, headers='keys', tablefmt='grid', floatfmt='.3f'))

# 对残差数据进行稳定性分析
residual_stability = stability_analysis(residuals, FIELDS_CORE, CORE_NAME_MAP)
print("\n【控制变量后残差数据不同阈值下的网络特征】")
print(tabulate(residual_stability, headers='keys', tablefmt='grid', floatfmt='.3f'))

# 可视化稳定性分析结果
fig, ax = plt.subplots(figsize=(10, 6))
metrics = ['网络密度', '平均度数', '连通分量数量']
for metric in metrics:
    ax.plot(stability_results['阈值'], 
            stability_results[metric].astype(float), 
            marker='o', 
            label=f'原始-{metric}')
    ax.plot(residual_stability['阈值'], 
            residual_stability[metric].astype(float), 
            marker='s', 
            linestyle='--',
            label=f'残差-{metric}')
ax.set_xlabel('相关系数阈值')
ax.set_ylabel('指标值')
ax.set_title('不同阈值下的网络特征变化', fontproperties=ch_font)
ax.legend(prop=ch_font)
ax.grid(True)
stability_fig_path = os.path.join(FIGURES_DIR, "网络稳定性分析.png")
plt.savefig(stability_fig_path, dpi=300, bbox_inches='tight')
plt.close()

if __name__ == "__main__":
    print("="*40)
    start_time_str = time.strftime('%Y-%m-%d %H:%M:%S')
    start_time = time.time()
    print(f"⏱ 代码尝试开始 {start_time_str}")
    print("="*40)

    # 在此处编写你的测试代码
    for _ in tqdm(range(5), colour='yellow'):
        time.sleep(0.2)

    end_time_str = time.strftime('%Y-%m-%d %H:%M:%S')
    end_time = time.time()
    print("="*40)
    print(f"⌛️ 代码尝试结束 {end_time_str}")
    duration = end_time - start_time
    print(f"总耗时：{int(duration)} 秒（{duration/60:.2f} 分钟）")
    print("="*40)
